package com.ruoyi.mobile.controller;

import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.security.service.TokenService;
import com.ruoyi.mobile.service.AuthService;
import com.ruoyi.mobile.service.ISysUserService;
import com.ruoyi.mobile.service.VerifyCodeService;
import com.ruoyi.mobile.utils.AppCode;
import com.ruoyi.mobile.utils.NftResponse;
import com.ruoyi.mobile.utils.ResponseConstants;
import com.ruoyi.mobile.utils.WxCode;
import com.ruoyi.mobile.utils.h5.CommenUtil;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.system.api.req.LoginReq;
import com.ruoyi.system.api.req.SysUserReq;
import com.ruoyi.system.api.resp.SysUserResp;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.core.web.controller.BaseController;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 登录验证模块
 * 
 * @author ruoyi
 */
@RestController
@RequestMapping("/auth")
public class AuthController extends BaseController
{
    @Autowired
    private VerifyCodeService verifyCodeService;

    @Autowired
    private AuthService authService;

    @Autowired
    private RemoteUserService remoteUserService;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private ISysUserService userService;

    @Resource
    private CommenUtil commenUtil;

    @Autowired
    private RedisTemplate redisTemplate;

    @ApiOperation(value="获取验证码")
    @GetMapping("/getPhoneCode")
    public NftResponse<Boolean> getPhoneCode(String phone) {
        return verifyCodeService.sendVerifyCode(phone);
    }

    @ApiOperation(value="验证码登录")
    @RequestMapping(value = "/loginByCode", method = RequestMethod.POST)
    public NftResponse<SysUserResp> loginByCode(@RequestBody LoginReq loginReq) {
        return authService.initAppUser(loginReq);
    }

    @ApiOperation(value="H5密码登录")
    @RequestMapping(value = "/login", method = RequestMethod.POST)
    public NftResponse<SysUserResp> login(@RequestBody LoginReq loginReq) {
        return authService.login(loginReq);
    }

    @ApiOperation(value="H5忘记密码")
    @RequestMapping(value = "/forget", method = RequestMethod.POST)
    public NftResponse<Boolean> forget(@RequestBody LoginReq loginReq) {
        Object failCountObject = redisTemplate.opsForValue().get("failCount:"+loginReq.getUserName());
        Integer failCount = 0;
        if(failCountObject != null){
            failCount = Integer.valueOf(failCountObject.toString());
            if(failCount >= 5){
                return new NftResponse<Boolean>(ResponseConstants.ERROR_CODE,"重试次数达5次，请稍后重试",false);
            }
        }
        Boolean verifyCodeResult = verifyCodeService.verifyCode(loginReq.getUserName(), loginReq.getPhoneCode());
        if(!verifyCodeResult){
            redisTemplate.opsForValue().set("failCount:"+ loginReq.getUserName(), failCount == null ? 1 : (failCount + 1),10*60*1000, TimeUnit.MILLISECONDS);
            return new NftResponse<Boolean>(ResponseConstants.ERROR_CODE,"验证码不正确",false);
        }
        NftResponse<SysUserResp> rtn = userService.getUserAppInfoByPhone(loginReq.getAppid(), loginReq.getUserName());
        if (rtn.getData() == null) {
            return new NftResponse<Boolean>(ResponseConstants.ERROR_CODE,"手机号不存在",false);
        }
        loginReq.setUserId(rtn.getData().getUserId());
        return userService.resetPass(loginReq);
    }

    @ApiOperation(value="退出登录")
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public NftResponse<Boolean> logout(@RequestHeader("userId") String userId) {
        return authService.logout(Integer.valueOf(userId));
    }

    @ApiOperation(value="获取微信小程序授权")
    @RequestMapping(value = "/putOpenid", method = RequestMethod.GET)
    public NftResponse<com.alibaba.fastjson.JSONObject> putOpenid(@RequestParam("code") String code,
                                                                  @RequestParam("appid") String appid) {
        com.alibaba.fastjson.JSONObject result = WxCode.getInstance().getMinOpenId(code, appid, AppCode.getValueByKey(appid));
        String openId = result.getString("openid");
        NftResponse<SysUserResp> rep = authService.getUserInfo(openId);
        SysUserResp u = rep.getData();
        Optional<SysUserResp> optional = Optional.ofNullable(u);
        if (optional.isPresent()) {
            R<LoginUser> userResult = remoteUserService.getUserInfo(u.getUserName(), SecurityConstants.INNER);
            LoginUser userInfo = userResult.getData();
            try {
                Map<String, Object> tokenMap = tokenService.createToken(userInfo);
                String token = (String) tokenMap.get("access_token");
                result = (JSONObject) com.alibaba.fastjson.JSONObject.toJSON(u);
                result.put("token", token);
            }catch (NullPointerException e) {}
        }
        return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "查询成功", result);
    }

    @ApiOperation(value="获取H5授权")
    @RequestMapping(value = "/getopenid", method = RequestMethod.POST)
    public NftResponse<Boolean> getopenid(@RequestBody LoginReq query) {
        String openId = WxCode.getInstance().getOpenId(query.getCode(), query.getAppid(), AppCode.getValueByKey(query.getAppid()));
        SysUserReq param = new SysUserReq();
        param.setUserId(Long.valueOf(query.getUserId()));

        param.setYwType(query.getYwtype());
        if ("2".equals(query.getYwtype())) {
            param.setFopenId(openId);
            param.setAppIdf(query.getAppid());
        }else if ("3".equals(query.getYwtype())) {
            param.setHopenId(openId);
            param.setAppId(query.getAppid());
        }
        return userService.updateUserAppInfo(param);
    }

    @ApiOperation(value="获取H5授权")
    @GetMapping("/getWXInterface")
    public NftResponse<Map<String, String>> getWXInterface(@RequestParam("url") String url,
                                                           @RequestParam("appid") String appid) {
        try {    // 前台encodeURIComponent加密后，后台解码，此url为前台动态传输
            url = java.net.URLDecoder.decode(url, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        Map<String, String> wxInitMap = this.commenUtil.getWxInitMap(url, appid, AppCode.getValueByKey(appid));
        return new NftResponse<>(ResponseConstants.SUCCESS_CODE, "获取成功", wxInitMap);
    }
}
